package com.ideaaedi.zoo.example.springboot.auditlog.openapi.config;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONWriter;
import com.google.common.collect.Sets;
import com.ideaaedi.zoo.diy.feature.auditlog.api.entity.AuditDTO;
import com.ideaaedi.zoo.diy.feature.auditlog.api.spi.AuditLogRecorder;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Nonnull;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Slf4j
@Component
public class DemoAuditLogRecorder implements AuditLogRecorder {
    
    private final Set<Class<?>> toIgnoreParamsClasses = Sets.newHashSet(MultipartFile.class, HttpServletRequest.class, HttpServletResponse.class, byte[].class);
    
    private final Set<Class<?>> toIgnoreResultClasses = Sets.newHashSet(byte[].class);
    
    @Override
    public void record(@Nonnull AuditDTO auditInfo) {
        Map<String, Object> requestParamMap = auditInfo.getRequestParamMap();
        Set<String> toIgnoreKey = new HashSet<>();
        requestParamMap.forEach((k, v) -> {
            if (v == null) {
                return;
            }
            boolean ignore = toIgnoreParamsClasses.stream().anyMatch(ignoreClass -> ignoreClass.isAssignableFrom(v.getClass()));
            if (ignore) {
                toIgnoreKey.add(k);
            }
        });
        for (String ignoreKey : toIgnoreKey) {
            Object value = requestParamMap.get(ignoreKey);
            requestParamMap.put(ignoreKey, "<hit ignore type '" + value.getClass().getName() + "'>");
        }
    
        Object responseResult = auditInfo.getResponseResult();
        if (responseResult != null && toIgnoreResultClasses.stream().anyMatch(ignoreClass -> ignoreClass.isAssignableFrom(responseResult.getClass()))) {
            auditInfo.setResponseResult("<hit ignore type '" + responseResult.getClass().getName() + "'>");
        }
        System.err.println(
                "发现审计日志：" + JSON.toJSONString(auditInfo, JSONWriter.Feature.NotWriteNumberClassName, JSONWriter.Feature.PrettyFormat)
        );
        try {
            TimeUnit.MILLISECONDS.sleep(200);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
}
